#include "global.h"
#include "utils/utils.h"

Global::Global()
    : m_waterType(0)
    , m_textSlope(0)
    , m_textDensity(0)
    , m_imageOpacity(0)
    , m_imageSlope(0)
    , m_imageScale(0)
    , m_imagePos(0)
    , m_qrSlope(0)
    , m_qrSize(0)
    , m_qrPos(0)
    , m_darkOpacity(0)
    , m_darkSlope(0)
    , m_darkDensity(0)
    , m_matrixDiam(0)
    , m_matrixLength(0)
    , m_matrixInterval(0)
{
    // 点阵码
    m_matrixCodeMap.insert("*", 0b0000000000010000111000000);
    m_matrixCodeMap.insert("0", 0b0000000000011100000000000);   //0000000000011100000000000
    m_matrixCodeMap.insert("1", 0b0000001000001000001000000);   //0000001000001000001000000
    m_matrixCodeMap.insert("2", 0b0000000100001000010000000);   //0000000100001000010000000
    m_matrixCodeMap.insert("3", 0b0000000010001000100000000);   //0000000010001000100000000
    m_matrixCodeMap.insert("4", 0b0000001010000000001000000);   //0000001000000000101000000
    m_matrixCodeMap.insert("5", 0b0000000010000000101000000);   //0000001010000000100000000
    m_matrixCodeMap.insert("6", 0b0000001000000000101000000);   //0000001010000000001000000
    m_matrixCodeMap.insert("7", 0b0000001010000000100000000);   //0000000010000000101000000
    m_matrixCodeMap.insert("8", 0b0000000000001100100000000);   //0000000010011000000000000
    m_matrixCodeMap.insert("9", 0b0000001000001000010000000);   //0000000100001000001000000
    m_matrixCodeMap.insert("A", 0b0000000010011000000000000);   //0000000000001100100000000
    m_matrixCodeMap.insert("B", 0b0000000100001000001000000);   //0000001000001000010000000
    m_matrixCodeMap.insert("C", 0b0000001000001100000000000);   //0000000000011000001000000
    m_matrixCodeMap.insert("D", 0b0000000010001000010000000);   //0000000100001000100000000
    m_matrixCodeMap.insert("E", 0b0000000000011000001000000);   //0000001000001100000000000
    m_matrixCodeMap.insert("F", 0b0000000100001000100000000);   //0000000010001000010000000

    initProcessList();
    initTextConfig();
    initImageConfig();
    initQrcoreConfig();
    initDarkConfig();
    initMatrixConfig();
}

Global &Global::instance()
{
    static Global s;
    return s;
}

ulong Global::waterType() const
{
    return m_waterType;
}

void Global::setWaterType(ulong value)
{
    m_waterType = value;
}

void Global::initProcessList()
{
    QVariantMap processMap =  ConfigIniUtil::readConfigValues(PathUtil::appConfig());
    if (processMap.isEmpty())
    {
        // 添加默认进程
        processMap.insert("notepad.exe", "记事本");
        ConfigIniUtil::writeConfigValues(PathUtil::appConfig(), "App", processMap);
    }
    m_processMap = processMap;
}

const QVariantMap &Global::processMap() const
{
    return m_processMap;
}

void Global::setProcessMap(const QVariantMap &value)
{
    m_processMap = value;
}

bool Global::isExistProcess(const QString &name) const
{
    return m_processMap.contains(name);
}

void Global::addProcess(const QString &name, const QString &desc)
{
    m_processMap.insert(name, desc);
    saveAppValue(name, desc);
}

void Global::delProcess(const QString &name)
{
    m_processMap.remove(name);
    deleteAppValue(name);
}

void Global::initTextConfig()
{
    QString configFile = PathUtil::config();

    QString textContent = ConfigIniUtil::readConfigValue(configFile, "Text/Content");
    m_textContent = QString::fromUtf8(QByteArray::fromBase64(textContent.toLocal8Bit()));

    QString textFontName = ConfigIniUtil::readConfigValue(configFile, "Text/FontName");
    QString textFontSize = ConfigIniUtil::readConfigValue(configFile, "Text/FontSize");
    if (textFontName.isEmpty() || textFontSize.isEmpty())
    {
        m_textFont.setFamily("微软雅黑");
        m_textFont.setPointSize(12);
    }
    else
    {
        m_textFont.setFamily(textFontName);
        m_textFont.setPointSize(textFontSize.toInt());
    }

    QString textColor = ConfigIniUtil::readConfigValue(configFile, "Text/Color");
    m_textColor = QColor(textColor.isEmpty() ? "black" : textColor);

    QString textOpacity = ConfigIniUtil::readConfigValue(configFile, "Text/Opacity");
    m_textColor.setAlpha(textOpacity.isEmpty() ? 100 : textOpacity.toInt());

    QString textSlope = ConfigIniUtil::readConfigValue(configFile, "Text/Slope");
    m_textSlope = textSlope.isEmpty() ? 0 : textSlope.toInt();

    QString textDensity = ConfigIniUtil::readConfigValue(configFile, "Text/Density");
    m_textDensity = textDensity.isEmpty() ? 120 : textDensity.toInt();
}

void Global::initImageConfig()
{
    QString configFile = PathUtil::config();

    QString imageFile = ConfigIniUtil::readConfigValue(configFile, "Image/File");
    if (FileUtil::isFileExist(imageFile))
    {
        m_imagePixmap.load(imageFile);
    }

    QString imageOpacity = ConfigIniUtil::readConfigValue(configFile, "Image/Opacity");
    m_imageOpacity = imageOpacity.isEmpty() ? 100 : imageOpacity.toInt();

    QString imageSlope = ConfigIniUtil::readConfigValue(configFile, "Image/Slope");
    m_imageSlope = imageSlope.isEmpty() ? 0 : imageSlope.toInt();

    QString imageScale = ConfigIniUtil::readConfigValue(configFile, "Image/Scale");
    m_imageScale = imageScale.isEmpty() ? 100 : imageScale.toInt();

    QString imagePos = ConfigIniUtil::readConfigValue(configFile, "Image/Pos");
    m_imagePos = imagePos.isEmpty() ? 0 : imagePos.toInt();
}

void Global::initQrcoreConfig()
{
    QString configFile = PathUtil::config();

    QString qrContent = ConfigIniUtil::readConfigValue(configFile, "QR/Content");
    m_qrContent = QString::fromUtf8(QByteArray::fromBase64(qrContent.toLocal8Bit()));

    QString qrColor = ConfigIniUtil::readConfigValue(configFile, "QR/Color");
    m_qrColor = QColor(qrColor.isEmpty() ? "black" : qrColor);

    QString qrOpacity = ConfigIniUtil::readConfigValue(configFile, "QR/Opacity");
    m_qrColor.setAlpha(qrOpacity.isEmpty() ? 100 : qrOpacity.toInt());

    QString qrSlope = ConfigIniUtil::readConfigValue(configFile, "QR/Slope");
    m_qrSlope = qrSlope.isEmpty() ? 0 : qrSlope.toInt();

    QString qrSize = ConfigIniUtil::readConfigValue(configFile, "QR/Size");
    m_qrSize = qrSize.isEmpty() ? 300 : qrSize.toInt();

    QString qrPos = ConfigIniUtil::readConfigValue(configFile, "QR/Pos");
    m_qrPos = qrPos.isEmpty() ? 0 : qrPos.toInt();
}

void Global::initDarkConfig()
{
    QString configFile = PathUtil::config();

    QString darkContent = ConfigIniUtil::readConfigValue(configFile, "Dark/Content");
    m_darkContent = QString::fromUtf8(QByteArray::fromBase64(darkContent.toLocal8Bit()));

    QString darkFontName = ConfigIniUtil::readConfigValue(configFile, "Dark/FontName");
    QString darkFontSize = ConfigIniUtil::readConfigValue(configFile, "Dark/FontSize");
    if (darkFontName.isEmpty() || darkFontSize.isEmpty())
    {
        m_darkFont.setFamily("微软雅黑");
        m_darkFont.setPointSize(12);
    }
    else
    {
        m_darkFont.setFamily(darkFontName);
        m_darkFont.setPointSize(darkFontSize.toInt());
    }

    QString darkColor = ConfigIniUtil::readConfigValue(configFile, "Dark/Color");
    m_darkColor = QColor(darkColor.isEmpty() ? "white" : darkColor);

    QString darkOpacity = ConfigIniUtil::readConfigValue(configFile, "Dark/Opacity");
    m_darkOpacity = darkOpacity.isEmpty() ? 5 : darkOpacity.toInt();

    QString darkSlope = ConfigIniUtil::readConfigValue(configFile, "Dark/Slope");
    m_darkSlope = darkSlope.isEmpty() ? 0 : darkSlope.toInt();

    QString darkDensity = ConfigIniUtil::readConfigValue(configFile, "Dark/Density");
    m_darkDensity = darkDensity.isEmpty() ? 120 : darkDensity.toInt();
}

void Global::initMatrixConfig()
{
    QString configFile = PathUtil::config();

    QString matrixContent = ConfigIniUtil::readConfigValue(configFile, "Matrix/Content");
    m_matrixContent = matrixContent;

    QString matrixColor = ConfigIniUtil::readConfigValue(configFile, "Matrix/Color");
    m_matrixColor = QColor(matrixColor.isEmpty() ? "red" : matrixColor);

    QString matrixOpacity = ConfigIniUtil::readConfigValue(configFile, "Matrix/Opacity");
    m_matrixColor.setAlpha(matrixOpacity.isEmpty() ? 255 : matrixOpacity.toInt());

    QString matrixDiam = ConfigIniUtil::readConfigValue(configFile, "Matrix/Diam");
    m_matrixDiam = matrixDiam.isEmpty() ? 1 : matrixDiam.toInt();

    QString matrixLength = ConfigIniUtil::readConfigValue(configFile, "Matrix/Length");
    m_matrixLength = matrixLength.isEmpty() ? 40 : matrixLength.toInt();

    QString matrixInterval = ConfigIniUtil::readConfigValue(configFile, "Matrix/Interval");
    m_matrixInterval = matrixInterval.isEmpty() ? 5 : matrixInterval.toInt();
}

const QString &Global::textContent() const
{
    return m_textContent;
}

void Global::setTextContent(const QString &value)
{
    m_textContent = value;
    saveValue("Text/Content", value.toUtf8().toBase64());
}

const QFont &Global::textFont() const
{
    return m_textFont;
}

void Global::setTextFont(const QFont &value)
{
    m_textFont = value;
    saveValue("Text/FontName", value.family());
    saveValue("Text/FontSize", value.pointSize());
}

int Global::textSlope() const
{
    return m_textSlope;
}

void Global::setTextSlope(int value)
{
    m_textSlope = value;
    saveValue("Text/Slope", value);
}

int Global::textOpacity() const
{
    return m_textColor.alpha();
}

void Global::setTextOpacity(int value)
{
    m_textColor.setAlpha(value);
    saveValue("Text/Opacity", value);
}

const QColor &Global::textColor() const
{
    return m_textColor;
}

void Global::setTextColor(const QColor &value)
{
    int opacity = m_textColor.alpha();
    m_textColor = value;
    m_textColor.setAlpha(opacity);
    saveValue("Text/Color", value.name());
}

int Global::textDensity() const
{
    return m_textDensity;
}

void Global::setTextDensity(int value)
{
    m_textDensity = value;
    saveValue("Text/Density", value);
}

const QPixmap &Global::imagePixmap() const
{
    return m_imagePixmap;
}

void Global::setImagePixmap(const QString &file)
{
    m_imagePixmap.load(file);
    saveValue("Image/File", file);
}

int Global::imageOpacity() const
{
    return m_imageOpacity;
}

void Global::setImageOpacity(int value)
{
    m_imageOpacity = value;
    saveValue("Image/Opacity", value);
}

int Global::imageSlope() const
{
    return m_imageSlope;
}

void Global::setImageSlope(int value)
{
    m_imageSlope = value;
    saveValue("Image/Slope", value);
}

int Global::imageScale() const
{
    return m_imageScale;
}

void Global::setImageScale(int value)
{
    m_imageScale = value;
    saveValue("Image/Scale", value);
}

int Global::imagePos() const
{
    return m_imagePos;
}

void Global::setImagePos(int value)
{
    m_imagePos = value;
    saveValue("Image/Pos", value);
}

const QString &Global::qrContent() const
{
    return m_qrContent;
}

void Global::setQrContent(const QString &value)
{
    m_qrContent = value;
    saveValue("QR/Content", value.toUtf8().toBase64());
}

const QColor &Global::qrColor() const
{
    return m_qrColor;
}

void Global::setQrColor(const QColor &value)
{
    m_qrColor = value;
    int opacity = m_qrColor.alpha();
    m_qrColor = value;
    m_qrColor.setAlpha(opacity);
    saveValue("QR/Color", value.name());
}

int Global::qrOpacity() const
{
    return m_qrColor.alpha();
}

void Global::setQrOpacity(int value)
{
    m_qrColor.setAlpha(value);
    saveValue("QR/Opacity", value);
}

int Global::qrSlope() const
{
    return m_qrSlope;
}

void Global::setQrSlope(int value)
{
    m_qrSlope = value;
    saveValue("QR/Slope", value);
}

int Global::qrSize() const
{
    return m_qrSize;
}

void Global::setQrSize(int value)
{
    m_qrSize = value;
    saveValue("QR/Size", value);
}

int Global::qrPos() const
{
    return m_qrPos;
}

void Global::setQrPos(int value)
{
    m_qrPos = value;
    saveValue("QR/Pos", value);
}

const QString &Global::darkContent() const
{
    return m_darkContent;
}

void Global::setDarkContent(const QString &value)
{
    m_darkContent = value;
    saveValue("Dark/Content", value.toUtf8().toBase64());
}

const QFont &Global::darkFont() const
{
    return m_darkFont;
}

void Global::setDarkFont(const QFont &value)
{
    m_darkFont = value;
    saveValue("Dark/FontName", value.family());
    saveValue("Dark/FontSize", value.pointSize());
}

const QColor &Global::darkColor() const
{
    return m_darkColor;
}

void Global::setDarkColor(const QColor &value)
{
    m_darkColor = value;
    saveValue("Dark/Color", value.name());
}

int Global::darkOpacity() const
{
    return m_darkOpacity;
}

void Global::setDarkOpacity(int value)
{
    m_darkOpacity = value;
    saveValue("Dark/Opacity", value);
}

int Global::darkSlope() const
{
    return m_darkSlope;
}

void Global::setDarkSlope(int value)
{
    m_darkSlope = value;
    saveValue("Dark/Slope", value);
}

int Global::darkDensity() const
{
    return m_darkDensity;
}

void Global::setDarkDensity(int value)
{
    m_darkDensity = value;
    saveValue("Dark/Density", value);
}

const QString &Global::matrixContent() const
{
    return m_matrixContent;
}

void Global::setMatrixContent(const QString &value)
{
    m_matrixContent = value;
    saveValue("Matrix/Content", value);
}

const QColor &Global::matrixColor() const
{
    return m_matrixColor;
}

void Global::setMatrixColor(const QColor &value)
{
    int opacity = m_matrixColor.alpha();
    m_matrixColor = value;
    m_matrixColor.setAlpha(opacity);
    saveValue("Matrix/Color", value.name());
}

int Global::matrixDiam() const
{
    return m_matrixDiam;
}

void Global::setMatrixDiam(int value)
{
    m_matrixDiam = value;
    saveValue("Matrix/Diam", value);
}

int Global::matrixOpacity() const
{
    return m_matrixColor.alpha();
}

void Global::setMatrixOpacity(int value)
{
    m_matrixColor.setAlpha(value);
    saveValue("Matrix/Opacity", value);
}

int Global::matrixLength() const
{
    return m_matrixLength;
}

void Global::setMatrixLength(int value)
{
    m_matrixLength = value;
    saveValue("Matrix/Length", value);
}

int Global::matrixInterval() const
{
    return m_matrixInterval;
}

void Global::setMatrixInterval(int value)
{
    m_matrixInterval = value;
    saveValue("Matrix/Interval", value);
}

uint32_t Global::matrixCodeByString(const QString &s)
{
    return m_matrixCodeMap.value(s);
}

void Global::saveValue(const QString &key, const QVariant &value)
{
    ConfigIniUtil::writeConfigValue(PathUtil::config(), key, value);
}

void Global::saveAppValue(const QString &name, const QString &desc)
{
    ConfigIniUtil::writeConfigValue(PathUtil::appConfig(), "App/" + name, desc);
}

void Global::deleteAppValue(const QString &name)
{
    ConfigIniUtil::deleteConfig(PathUtil::appConfig(), "App/" + name);
}

